/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2023. All rights reserved.
 */

package dao

import (
	"fmt"
	"prim-server/common"
	"prim-server/model"

	"github.com/astaxie/beego/orm"
	"github.com/pkg/errors"
	"github.com/spf13/cast"
)

type CreditRecordDao struct {
	BaseDao
}

type ICreditRecordDAo interface {
	SaveCreditRecordInfo(creditRecord *model.CreditRecord) error
	DeleteCreditRecordInfo(userId string) error
	UpdateCreditRecordInfo(creditRecord *model.CreditRecord) error
	GetCreditRecordInfo(queryParameter *common.QueryCreditRecordDetail) (creditRecords []*model.CreditRecord, totalCount int, err error)
}

func GetCreditRecordDao() ICreditRecordDAo {
	dao := &CreditRecordDao{}
	dao.Init()
	return dao
}

func (crd *CreditRecordDao) SaveCreditRecordInfo(creditRecord *model.CreditRecord) error {
	if creditRecord == nil {
		return nil
	}
	_, err := crd.O.Insert(creditRecord)
	if err != nil {
		return errors.Errorf("SaveCreditRecordInfo error: %v, userId: %s", err, creditRecord.UserId)
	}
	return nil
}

func (crd *CreditRecordDao) DeleteCreditRecordInfo(userId string) error {
	if len(userId) == 0 {
		return nil
	}
	creditRecord := new(model.CreditRecord)
	creditRecord.UserId = userId
	_, err := crd.O.Delete(creditRecord, "user_id")
	if err != nil {
		return errors.Errorf("DeleteCreditRecordInfo error: %v, userId: %s", err, userId)
	}
	return nil
}
func (crd *CreditRecordDao) UpdateCreditRecordInfo(creditRecord *model.CreditRecord) error {
	if creditRecord == nil {
		return nil
	}
	_, err := crd.O.Update(creditRecord)
	if err != nil {
		return errors.Errorf("UpdateCreditRecordInfo error: %v, userId: %s", err, creditRecord.UserId)
	}
	return nil
}
func (crd *CreditRecordDao) GetCreditRecordInfo(queryParameter *common.QueryCreditRecordDetail) (creditRecords []*model.CreditRecord, totalCount int, err error) {
	if queryParameter == nil {
		return nil, 0, nil
	}
	recode := crd.O.QueryTable(&model.CreditRecord{})
	finalCondition := orm.NewCondition()
	if len(queryParameter.CreditRecordId) > 0 {
		finalCondition = finalCondition.And("credit_record_id__in", queryParameter.CreditRecordId)
	}
	if len(queryParameter.UserId) > 0 {
		finalCondition = finalCondition.And("user_id__in", queryParameter.UserId)
	}
	if len(queryParameter.OperationType) > 0 {
		finalCondition = finalCondition.And("operation_type__in", queryParameter.OperationType)
	}
	if queryParameter.OperationTimeBegin != nil && queryParameter.OperationTimeEnd != nil {
		operationTimeCondition := orm.NewCondition()
		operationTimeCondition = operationTimeCondition.And("operation_time__gte", crd.ConvertToUTC(*queryParameter.OperationTimeBegin)).And("operation_time__lte", crd.ConvertToUTC(*queryParameter.OperationTimeEnd))
		finalCondition = finalCondition.AndCond(operationTimeCondition)
	}
	if queryParameter.Currency != nil {
		finalCondition = finalCondition.And("currency", *queryParameter.Currency)
	}
	if queryParameter.ExpireTimeBegin != nil && queryParameter.ExpireTimeEnd != nil {
		expireTimeCondition := orm.NewCondition()
		expireTimeCondition = expireTimeCondition.And("expire_time__gte", crd.ConvertToUTC(*queryParameter.ExpireTimeBegin)).And("expire_time__lte", crd.ConvertToUTC(*queryParameter.ExpireTimeEnd))
		finalCondition = finalCondition.AndCond(expireTimeCondition)
	}
	offset, pageSize := crd.GetOffsetAndPageSize(queryParameter.Page, queryParameter.PageSize)
	recode = recode.SetCond(finalCondition)
	totalCount64, err := recode.Count()
	if err != nil {
		return nil, 0, errors.Errorf("GetCreditRecordInfo error: %v, userId: %s", err, fmt.Sprint(queryParameter.UserId))
	}
	totalCount = cast.ToInt(totalCount64)
	_, err = recode.Offset(offset).Limit(pageSize).All(&creditRecords)
	if err != nil {
		if err == orm.ErrNoRows {
			//not found
			return nil, 0, nil
		}
		//found error
		return nil, 0, errors.Errorf("GetCreditRecordInfo error: %v, userId: %s", err, fmt.Sprint(queryParameter.UserId))
	}
	return creditRecords, totalCount, nil
}
